using System.IO;
using System.Linq;
using System.Web;
using System.Web.Caching;
using Toast.Caching;
using Toast.ContentTypes;
using Toast.Core.Interfaces;
using Toast.Extensions;
using Toast.Utils;

namespace Toast.HttpHandlers
{
    public class ToastHttpHandler : IHttpHandler
    {
        #region IHttpHandler Members

        public void ProcessRequest(HttpContext context)
        {
            var key = context.Request.QueryString["d"];
            var packageKey = context.Request.QueryString["p"];

            WriteResponseContent(packageKey, key, context.Response);
        }

        public bool IsReusable
        {
            get { return false; }
        }

        #endregion

        static void WriteResponseContent(string packageKey, string key, HttpResponse response)
        {
            //TODO: Why is this check necessary? 
            if (key.IsNullOrEmpty())
                return;

            var package = RequestPackageCache.Get(packageKey).Where(x => x is ICompressable).Select(y => y as ICompressable);

            var requestedKeys = key.Split('~').Select(x => EncodingUtils.UrlSafeDecode(x));

            var scripts = (from s in requestedKeys
                           join c in package on s equals c.Id
                           select c);

            foreach (var a in scripts.GroupBy(y=>y.HttpContentType))
            {
                var content = HttpRuntimeCacheService.Get(key, () =>
                {
                    var combined = a
                        .Where(x => File.Exists(x.FullPath))
                        .Distinct()
                        .GroupBy(x => x.Compression)
                        .Aggregate(string.Empty, (current, script) => current + script.Key.Compress(script.Select(x => File.ReadAllText(x.FullPath)).Join("\r\n")));

                    return combined;
                }, new CacheDependency(scripts.Select(x => x.FullPath).ToArray()));

                response.ContentType = a.Key;
                response.Write(content);
            }

        }
    }
}